package com.inspector.app.ui.widget;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.ColorDrawable;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.appcompat.widget.AppCompatButton;
import androidx.core.content.ContextCompat;

import com.inspector.app.R;


import java.io.File;

public class RecordButton extends AppCompatButton {


    private String mFile;


    private OnFinishedRecordListener finishedListener;
    /**
     * 最短录音时间
     **/
    private int MIN_INTERVAL_TIME = 1000;
    /**
     * 最长录音时间
     **/
    private int MAX_INTERVAL_TIME = 1000 * 60;


    private static View view;

    private TextView mStateTV;

    private ImageView mStateIV;

    private MediaRecorder mRecorder;
    private ObtainDecibelThread mThread;
    private Handler volumeHandler;
    private boolean isRecording = false;
    private AnimationDrawable anim;
    private MediaPlayer mediaPlayer;
    private float y;

    public RecordButton(Context context) {
        super(context);
        init();
    }

    public RecordButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public RecordButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }


    public void setOnFinishedRecordListener(OnFinishedRecordListener listener) {
        finishedListener = listener;
    }


    private static long startTime;
    private Dialog recordDialog;
    private static int[] res = {R.drawable.ic_volume_0, R.drawable.ic_volume_1, R.drawable.ic_volume_2,
            R.drawable.ic_volume_3, R.drawable.ic_volume_4, R.drawable.ic_volume_5, R.drawable.ic_volume_6
            , R.drawable.ic_volume_7, R.drawable.ic_volume_8};


    @SuppressLint("HandlerLeak")
    private void init() {

        volumeHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == -100) {
                    stopRecording();
                    recordDialog.dismiss();
                } else if (msg.what != -1) {
                    mStateIV.setImageResource(res[msg.what]);
                }
            }
        };
    }


    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        y = event.getY();
        handleTouchActions(event.getAction());
        return true;
    }

    private void handleTouchActions(int action) {
        if (mStateTV != null && mStateIV != null && y < 0) {
            mStateTV.setText("松开手指,取消发送");
            mStateIV.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_volume_cancel));
        } else if (mStateTV != null) {
            mStateTV.setText("手指上滑,取消发送");
        }

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                setText("松开发送");
                if (!isRecording) {
                    initDialogAndStartRecord();
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                this.setText("按住录音");
                if (y >= 0 && (System.currentTimeMillis() - startTime <= MAX_INTERVAL_TIME)) {
                    finishRecord();
                } else if (y < 0) {
                    cancelRecord();
                }
                break;
        }
    }

    /**
     * 初始化录音对话框 并 开始录音
     */
    private void initDialogAndStartRecord() {
        mFile = getContext().getFilesDir() + "/" + "voice_" + System.currentTimeMillis() + ".mp3";
        startTime = System.currentTimeMillis();
        recordDialog = new Dialog(getContext(), R.style.like_toast_dialog_style);
        recordDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        view = View.inflate(getContext(), R.layout.dialog_record, null);
        mStateIV = view.findViewById(R.id.rc_audio_state_image);
        mStateTV = view.findViewById(R.id.rc_audio_state_text);
        mStateIV.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.anim_mic));
        anim = (AnimationDrawable) mStateIV.getDrawable();
        anim.start();
        mStateIV.setVisibility(View.VISIBLE);
        mStateTV.setVisibility(View.VISIBLE);
        mStateTV.setText("手指上滑,取消发送");
        recordDialog.setContentView(view, new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));
        recordDialog.setOnDismissListener(onDismiss);
        WindowManager.LayoutParams lp = recordDialog.getWindow().getAttributes();
        lp.gravity = Gravity.CENTER;
        startRecording();
        recordDialog.show();
    }

    /**
     * 放开手指，结束录音处理
     */
    private void finishRecord() {
        long intervalTime = System.currentTimeMillis() - startTime;
        if (intervalTime < MIN_INTERVAL_TIME) {
            volumeHandler.sendEmptyMessageDelayed(-100, 500);
            mStateIV.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_volume_wraning));
            mStateTV.setText("录音时间太短");
            anim.stop();
            File file = new File(mFile);
            file.delete();
        /*    stopRecording();
            recordDialog.dismiss();*/
            return;
        } else {
            stopRecording();
            recordDialog.dismiss();
        }
        mediaPlayer = new MediaPlayer();
        try {
            mediaPlayer.setDataSource(mFile);
            mediaPlayer.prepare();
            mediaPlayer.getDuration();
        } catch (Exception e) {

        }

        if (finishedListener != null)
            finishedListener.onFinishedRecord(mFile, mediaPlayer.getDuration() / 1000);

    }

    /**
     * 取消录音对话框和停止录音
     */
    public void cancelRecord() {
        stopRecording();
        recordDialog.dismiss();
        File file = new File(mFile);
        file.delete();
    }

    //获取类的实例
    // ExtAudioRecorder extAudioRecorder; //压缩的录音（WAV）

    /**
     * 执行录音操作
     */
    //int num = 0 ;
    private void startRecording() {
        if (mRecorder == null) {
            mRecorder = new MediaRecorder();
        }
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        File file = new File(mFile);
        mRecorder.setOutputFile(mFile);
        try {
            if (!isRecording) {
                mRecorder.prepare();
                isRecording = true;
            }
            mRecorder.start();
//            mThread = new ObtainDecibelThread(mRecorder, volumeHandler, startTime);
//            mThread.start();
        } catch (Exception e) {
            e.printStackTrace();
            if (mRecorder != null) {
                mRecorder.release();
                mRecorder = null;
            }
            startRecording();
        }

    }


    private void stopRecording() {

        if (mThread != null) {
            mThread.exit();
            mThread = null;
        }
        if (mRecorder != null) {
            try {
                if (isRecording) {
                    mRecorder.stop();
                    mRecorder.reset();
                    mRecorder.release();
                    mRecorder = null;
                    isRecording = false;
                }
            } catch (RuntimeException e) {

            }
        }

        if (volumeHandler != null) {
            volumeHandler.removeCallbacksAndMessages(-100);
            volumeHandler = null;
        }


    }


    public class ObtainDecibelThread extends Thread {

        private static final String TAG = "ObtainDecibelThread";
        private static final int MAX_DB_LEVEL = 7; // 最大音量级别
        private static final int DB_STEP = 5; // dB级别步长

        private final MediaRecorder mRecorder;
        private final Handler volumeHandler;
        private volatile boolean running = true;
        private final long startTime;

        public ObtainDecibelThread(MediaRecorder recorder, Handler handler, long startTime) {
            this.mRecorder = recorder;
            this.volumeHandler = handler;
            this.startTime = startTime;
        }

        public void exit() {
            running = false;
        }

        @Override
        public void run() {
            try {
                while (running) {
                    if (mRecorder == null || !running) {
                        break;
                    }
                    int amplitude = mRecorder.getMaxAmplitude();
                    double db = 20 * Math.log10(Math.max(1, amplitude / 32767.0)); // 防止log(0)
                    int level = Math.min(MAX_DB_LEVEL, (int) (db / DB_STEP));
                    volumeHandler.sendEmptyMessage(level);

                    if (System.currentTimeMillis() - startTime > 20000) {
                        volumeHandler.sendEmptyMessage(-100); // 发送结束录音的消息
                        running = false;
                    }

                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                Log.e(TAG, "Interrupted", e);
            } catch (Exception e) {
                Log.e(TAG, "Error in ObtainDecibelThread", e);
            }
        }
    }


    private DialogInterface.OnDismissListener onDismiss = dialog -> stopRecording();

    public interface OnFinishedRecordListener {
        public void onFinishedRecord(String audioPath, int time);
    }


}
